www.gusucode.com > VC++ 界面很酷的一款多媒体播放器 > VC++ 界面很酷的一款多媒体播放器/gusucode/xMedia代码注释中/player.cpp
//Download by http://www.NewXing.com /**************************************** * File: player.cpp * * Last modified: 2004.3.24 * * Author: Yuanyi-Zhang * * Version: 0.0.1.0 * * CopyLeft 2004 xMedia team * ****************************************/ /**************************************************************** * * * This file may be distributed and/or modified under the terms * * of the GNU General Public License version 2 as published by * * the Free Software Foundation and appearing in the file * * LICENSE.GPL included in the packaging of this file. * * * ****************************************************************/ #pragma warning(disable:4786) #include <tchar.h> #include "player.h" #include "messagedef.h" Player::Player() { m_pGraph = NULL; m_pMediaControl = NULL; m_pEvent = NULL; m_pVidWin = NULL; m_pSeeking = NULL; m_PlayState = Uninited; m_AudioOnly = true; m_fnameBuf = _T(""); m_pBA = NULL; m_pBV = NULL; } ///////////////////////////////// //初始化DirectShow设备 bool Player::initDevice() { CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGraph); if( m_pGraph == NULL ) { m_ErrorString = _T("创建DirectShow组件失败"); return false; } m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVidWin); m_pGraph->QueryInterface( IID_IMediaEventEx, (void **)&m_pEvent); m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl); m_pGraph->QueryInterface( IID_IMediaSeeking, (void**)&m_pSeeking ); m_pGraph->QueryInterface( IID_IBasicVideo, (void**)&m_pBV ); m_pGraph->QueryInterface( IID_IBasicAudio, (void**)&m_pBA ); if( m_pSeeking == NULL || m_pMediaControl == NULL || m_pEvent == NULL || m_pBA == NULL ) { m_ErrorString = _T("创建DirectShow组件失败"); return false; } m_PlayState = Inited; return true; } /////////////////////////////// //打开指定文件 bool Player::Open( string filePath ) { if( m_fnameBuf.compare( filePath ) == 0 && m_PlayState != Uninited ) { return true; } if( m_PlayState != Uninited ) { Close(); } m_fnameBuf = filePath; if( !initDevice() ) { return false; } if( ! m_pGraph || ! m_pMediaControl ) { m_ErrorString = _T("DirectDraw未被正确初始化"); return false; } HRESULT hres; unsigned short wcFileName[MAX_PATH]; MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED, filePath.c_str(), filePath.size()+1, wcFileName,MAX_PATH); hres = m_pGraph->RenderFile( wcFileName, NULL ); if( !checkRes( hres ) ) { return false; } long videoWidth; if( !m_pBV ) { m_AudioOnly = true; } else { hres = m_pBV->get_VideoWidth( &videoWidth ); if( checkRes( hres ) ) { m_AudioOnly = false; } else { m_AudioOnly = true; } } if( !m_AudioOnly ) { ShowWindow( m_hWndVideo, SW_SHOW ); hres = m_pVidWin->put_Owner((OAHWND)m_hWndVideo); if( !checkRes( hres ) ) { return false; } hres = m_pVidWin->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS); if( !checkRes( hres ) ) { return false; } m_pVidWin->put_Left( m_VideoWndRect.left ); m_pVidWin->put_Top( m_VideoWndRect.top ); m_pVidWin->put_Width( m_VideoWndRect.right - m_VideoWndRect.left ); m_pVidWin->put_Height( m_VideoWndRect.bottom - m_VideoWndRect.top ); } return true; } /////////////////////////////// //关闭DirectShow设备 void Player::Close() { if( m_pMediaControl ) { m_pMediaControl->Stop(); } m_PlayState = Uninited; m_AudioOnly = true; m_FullScreen = false; ShowWindow( m_hWndVideo, SW_HIDE ); ReleaseResource(); } /////////////////////////////// //释放资源 void Player::ReleaseResource() { //清除DirectShow组件 if( m_pVidWin ) { m_pVidWin->put_Visible( OAFALSE ); m_pVidWin->put_Owner( NULL ); m_pVidWin = NULL; } if( m_pEvent ) { m_pEvent->SetNotifyWindow( NULL, 0, 0 ); m_pEvent->Release(); m_pEvent = NULL; } if( m_pMediaControl ) { m_pMediaControl->Stop(); m_pMediaControl->Release(); m_pMediaControl = NULL; } if( m_pBV ) { m_pBV->Release(); m_pBV = NULL; } if( m_pBA ) { m_pBA->Release(); m_pBA = NULL; } if( m_pGraph ) { m_pGraph->Release(); m_pGraph = NULL; } } //////////////////////////////////// //播放文件 bool Player::Play( string filePath ) { if( !Open( filePath ) ) { return false; } if( m_PlayState == Running ) { return true; } HRESULT hres = m_pMediaControl->Run(); m_PlayState = Running; return checkRes( hres ); } /////////////////////////////// //停止播放 bool Player::Stop() { if( m_PlayState != Running && m_PlayState != Paused ) { return true; } HRESULT hres = m_pMediaControl->Stop(); LONGLONG pos = 0; m_pSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning , NULL, AM_SEEKING_NoPositioning); m_pMediaControl->Pause(); m_PlayState = Stopped; return true; } /////////////////////////////// //暂停播放 bool Player::Pause() { if( m_PlayState != Running ) { return false; } HRESULT hres = m_pMediaControl->Pause(); m_PlayState = Paused; return checkRes( hres ); } /////////////////////////////// //检查返回值是否有效 bool Player::checkRes( HRESULT hres ) { switch( hres ) { case E_FAIL: m_ErrorString = _T("播放失败,可能是由于设备未被初始化"); return false; case E_INVALIDARG: m_ErrorString = _T("播放失败,错误的参数"); return false; case E_NOTIMPL: m_ErrorString = _T("播放失败,接口不支持此方法"); return false; case E_OUTOFMEMORY: m_ErrorString = _T("播放失败,没有足够的缓冲区用于播放此文件"); return false; case E_POINTER: m_ErrorString = _T("播放失败,参数含有空指针"); return false; case E_UNEXPECTED: m_ErrorString = _T("播放失败,不可预测的错误"); return false; case S_FALSE: case S_OK: return true; } return false; } ///////////////////////////// //定位播放进度 bool Player::seeking( int prog ) { if( m_PlayState == Uninited ) { m_ErrorString = _T("组件未被初始化"); return false; } LONGLONG playTime,length; m_pSeeking->GetDuration( &length ); playTime = (length * prog) / 100; m_pSeeking->SetPositions( &playTime, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning ); return true; } ///////////////////////////// //获取播放Bps,未实现 long Player::getBPS() { if( m_PlayState != Uninited ) { return 192; } return 0; } ///////////////////////////// //获取播放曲目长度 long Player::getLength() { LONGLONG length; if( m_pSeeking ) { m_pSeeking->GetDuration( &length ); return length/10000000; } return 0; } ///////////////////////////// //获取播放进度 int Player::getPlayProg() { if( m_PlayState == Uninited ) { return 0; } LONGLONG playTime,length; m_pSeeking->GetPositions( &playTime, &length ); m_pSeeking->GetDuration( &length ); if( playTime == length ) { Close(); PostThreadMessage( GetCurrentThreadId(), MC_PLAYNEXT, 0, 0 ); return 0; } return (int)((playTime*100)/length); }